﻿using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class ShipUIData
{
    public string m_UIName ="None";
    public int m_Id;
    public Vector2 m_SizeScale;
    public Vector2 m_PositionScale;
    public ShipUI.ShipUIType m_Type;
    public bool m_ShowJustInAndroid = false;

    public virtual JsonData Save()
    {
        JsonData root = new JsonData();

        root["UIName"] = m_UIName;
        root["ID"] = m_Id;
        root["SizeScaleX"] = Math.Round(m_SizeScale.x, 3);
        root["SizeScaleY"] = Math.Round(m_SizeScale.y, 3);

        root["PositionScaleX"] = Math.Round(m_PositionScale.x, 3);
        root["PositionScaleY"] = Math.Round(m_PositionScale.y, 3);
        root["ShipUIType"] = (int)m_Type;
        root["ShowJustInAndroid"] = m_ShowJustInAndroid;
        return root;
    }
    public virtual bool Load(JsonData root)
    {
        IDictionary<string, JsonData> rootObj = root.ValueAsObject();

        if (rootObj.ContainsKey("UIName"))
            m_UIName = rootObj["UIName"].ValueAsString();
        if (rootObj.ContainsKey("ID"))
            m_Id = rootObj["ID"].ValueAsInt();
        if (rootObj.ContainsKey("ShipUIType"))
            m_Type = (ShipUI.ShipUIType)rootObj["ShipUIType"].ValueAsInt();
        if (rootObj.ContainsKey("ShowJustInAndroid"))
            m_ShowJustInAndroid = rootObj["ShowJustInAndroid"].ValueAsBoolean();

        Vector2 sizeScale = new Vector2();
        if (rootObj.ContainsKey("SizeScaleX"))
            sizeScale.x = (float)rootObj["SizeScaleX"].ValueAsDouble();
        if (rootObj.ContainsKey("SizeScaleY"))
            sizeScale.y = (float)rootObj["SizeScaleY"].ValueAsDouble();
        m_SizeScale = sizeScale;
        Vector2 positionScale = new Vector2();
        if (rootObj.ContainsKey("PositionScaleX"))
            positionScale.x = (float)rootObj["PositionScaleX"].ValueAsDouble();
        if (rootObj.ContainsKey("PositionScaleY"))
            positionScale.y = (float)rootObj["PositionScaleY"].ValueAsDouble();
        m_PositionScale = positionScale;
        return true;
    }
}

public class ShipUI : MonoBehaviour
{
    public enum ShipUIType
    {
        None,
        Button,
        MovePole,
        ProgressBar,
        ShipInfo,

    }
    public string uiName { 
        get { return m_ShipUIData.m_UIName; }
        set { m_ShipUIData.m_UIName = value; } 
    }
    public int id
    {
        get { return m_ShipUIData.m_Id; }
        set { m_ShipUIData.m_Id = value; }
    }
    public Vector2 sizeScale
    {
        get { return m_ShipUIData.m_SizeScale; }
        set { m_ShipUIData.m_SizeScale = value; }
    }
    public Vector2 positionScale
    {
        get { return m_ShipUIData.m_PositionScale; }
        set { m_ShipUIData.m_PositionScale = value; }
    }
    public ShipUIData shipUIData
    {
        get { return m_ShipUIData; }
        set { m_ShipUIData = value; }
    }
    bool editMode { get; set; } = false;


    protected ShipUIData m_ShipUIData = new ShipUIData();
    public ShipUIType m_Type;
    protected Ship m_Ship;
    public static List<ShipUI> shipUIPrefabs { get { return m_ShipUIPrefabs; } }
    static List<ShipUI> m_ShipUIPrefabs = new List<ShipUI>();
    public Sprite m_PreviewPrefab;
    void Start()
    {
    }
    private void OnEnable()
    {
        if (m_ShipUIData.m_ShowJustInAndroid && !Utils.IsAndroid() && !editMode)
            HideAllTheImages(gameObject);
    }
    // Update is called once per frame
    void Update()
    {

    }
    public virtual void BindShip(Ship ship)
    {
        m_Ship = ship;
    }
    public void HideAllTheImages(GameObject gameObj)
    {
        var image = gameObj.GetComponent<Image>();
        if (image)
            image.enabled = false;
        for (int i = 0; i < gameObj.transform.childCount; ++i)
        {
            var gameObjChild = gameObj.transform.GetChild(i);
            HideAllTheImages(gameObjChild.gameObject);
        }
    }
    public virtual void ApplyData()
    {
        transform.position = new Vector3(positionScale.x * Screen.width, positionScale.y * Screen.height);
        transform.localScale = new Vector3(1, 1, 1);
        GetComponent<RectTransform>().sizeDelta = new Vector3(sizeScale.x * Screen.width, sizeScale.y * Screen.height);
        SetEditMode(false);
    }
    public void ClearAllTheOperationEvent()
    {
        for (int i = 1; i < 100; ++i)
        {
            var operationEvent = GetOperationEvent(i);
            if (operationEvent == null)
                break;
            operationEvent.RemoveAllListeners();
        }
    }
    public virtual string GetTypeName()
    {
        return "None";
    }
    public List<string> GetOperationList()
    {
        var operationList = new List<string>();
        operationList.Add("NONE");
        for (int i = 1; i < 100; ++i)
        {
            var operationEvent = GetOperationEvent(i);
            if (operationEvent == null)
                break;
            operationList.Add(GetOperationName(i));
        }

        return operationList;
    }
    public void BindOperationEvent(int operationType, UnityAction action)
    {
        UnityEvent selectedEvent = GetOperationEvent(operationType);
        if (selectedEvent == null)
            return;
        selectedEvent.AddListener(action);
    }
    public void UnbindOperationEvent(int operationType, UnityAction action)
    {
        UnityEvent selectedEvent = GetOperationEvent(operationType);
        if (selectedEvent == null)
            return;
        selectedEvent.RemoveListener(action);
    }
    public virtual UnityEvent GetOperationEvent(int operationType)
    {
        return null;
    }

    public virtual void SetEditMode(bool isEditMode)
    {
        editMode = isEditMode;
        SetRaycastTarget(gameObject, !isEditMode);
    }

    protected void SetRaycastTarget(GameObject obj, bool isEnabled)
    {
        for (int i = 0; i < obj.transform.childCount; ++i)
        {
            var child = obj.transform.GetChild(i);
            SetRaycastTarget(child.gameObject, isEnabled);
        }
        var image = obj.GetComponent<Image>();
        var text = obj.GetComponent<Text>();
        if (image)
            image.raycastTarget = isEnabled;
        if (text)
            text.raycastTarget = isEnabled;
    }
    public virtual string GetOperationName(int operation)
    {
        return "None";
    }


    static public ShipUI Create(ShipUI.ShipUIType type)
    {
        foreach (var i in m_ShipUIPrefabs)
        {
            if (i.m_Type == type)
            {
                var newShipUI = GameObject.Instantiate(i);
                return newShipUI;
            }
        }
        return null;
    }

    public static void InitShipUIPrefabs()
    {
        var object2 = Resources.LoadAll(Utils._SHIP_UI_PATH_);
        for (int i = 0; i < object2.Length; ++i)
        {
            var gobj = object2[i] as GameObject;
            if (gobj != null)
                m_ShipUIPrefabs.Add(gobj.GetComponent<ShipUI>());
        }
    }
    static public ShipUI.ShipUIType GetShipUIType(JsonData root)
    {
        IDictionary<string, JsonData> rootObj = root.ValueAsObject();
        if (!rootObj.ContainsKey("ShipUIType"))
            return ShipUIType.None;
        return (ShipUIType)rootObj["ShipUIType"].ValueAsInt();
    }
}